package com.hson.demo.base.crypter;

import org.keyczar.AesKey;
import org.keyczar.Crypter;
import org.keyczar.DefaultKeyType;
import org.keyczar.HmacKey;
import org.keyczar.KeyMetadata;
import org.keyczar.KeyczarKey;
import org.keyczar.MockKeyczarReader;
import org.keyczar.enums.KeyPurpose;
import org.keyczar.exceptions.KeyczarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class CrypterManager {

	private static final Logger logger = LoggerFactory.getLogger(CrypterManager.class);
	
	static {
		FixBrokenCipherSpiProvider.insertIfNeeded();
	}
	
	private Crypter crypter;
	
	public CrypterManager() {
		try {
			initMock();
		} catch (KeyczarException e) {
			logger.error("Could not initialize the Crypter");
			String fileLocation = this.getClass().getClassLoader().getResource("keys").getPath();
			try {
				crypter = new Crypter(fileLocation);
			} catch (KeyczarException e1) {
				logger.error("Could not initialize the Crypter with the file location[" + fileLocation + "]");
			}
		}
	}
	
	private void initMock() throws KeyczarException {
		String name = "cantonfair";
		MockKeyczarReader reader = new MockKeyczarReader(name, KeyPurpose.DECRYPT_AND_ENCRYPT, DefaultKeyType.AES);
		
		String str = "{\"name\":\"cantonfair\",\"purpose\":\"DECRYPT_AND_ENCRYPT\",\"type\":\"AES\",\"versions\":[{\"exportable\":false,\"status\":\"PRIMARY\",\"versionNumber\":1}],\"encrypted\":false}";
		KeyMetadata newKmd = KeyMetadata.read(str);
		reader.setMetadata(newKmd);
		
		byte[] keyBytes = new String("{\"hmacKeyString\":\"tce4NMdpzo1EPeEO5rNQgvi9V5Bu3zibNy3hNquzuMo\",\"size\":256}").getBytes();
		HmacKey hmacKey = new HmacKey(keyBytes);
		byte[] aesKeyBytes = new String("B_ZYgoQXtLxfb8EJQHnLYA").getBytes();
		KeyczarKey key = new AesKey(aesKeyBytes, hmacKey);
		reader.setKey(1, key.getType().getBuilder().read("{\"aesKeyString\":\"B_ZYgoQXtLxfb8EJQHnLYA\",\"hmacKey\":{\"hmacKeyString\":\"tce4NMdpzo1EPeEO5rNQgvi9V5Bu3zibNy3hNquzuMo\",\"size\":256},\"mode\":\"CBC\",\"size\":128}"));
		
		crypter = new Crypter(reader);
	}
	
	public String encrypt(String source) {
		if(crypter != null) {
			try {
				return crypter.encrypt(source);
			} catch (KeyczarException e) {
				logger.error("Could not encrypt the source[" + source + "]");
			} 
		}
		return source;
	}
	
	public String decrypt(String ciphertext) {
		if(crypter != null) {
			try {
				return crypter.decrypt(ciphertext);
			} catch (KeyczarException e) {
				logger.error("Could not decrypt the ciphertext[" + ciphertext + "]");
			}
		}
		return ciphertext;
	}
	
	public static void main(String[] args) {
		CrypterManager manager = new CrypterManager();
		System.out.println(manager.decrypt("kamen"));
		
		manager = new CrypterManager();
		System.out.println(manager.decrypt(manager.encrypt("lijie@cf-ec.com")));
		
	}
}
